﻿using System;
using System.Linq;
using System.Web.Mvc;
using Storytelling.Entidades;
using Storytelling.Modelos;
using Storytelling.Negocio;
using Storytelling.Utils;
using Storytelling.Negocio.Excecoes;

namespace Storytelling.Controllers
{
    public abstract class BaseCrudController<T, TEntidadeFormModel> : Controller
        where T : Nomeado
        where TEntidadeFormModel : EntidadeFormModel<T>
    {
        protected abstract IServico<T, TEntidadeFormModel> Servico { get; }

        protected virtual void EscolherCarregamento(Carga<T> carga, TipoCarregamento tipo)
        {
        }

        protected string MensagemExcecao 
        {
            set
            {
                TempData["MensagemExcecao"] = value;
            }
        }

        [Authorize]
        public virtual ActionResult Index(FiltrarModel<T> model)
        {
            EscolherCarregamento(model.Carga, TipoCarregamento.Varios);
            Servico.Filtrar(model);          
            return View(model);
        }

        [Authorize]
        public virtual JsonResult Autocompletar(string nome)
        {
            FiltrarModel<T> model = new FiltrarModel<T>();
            model.Inativados = false;
            model.Exemplo.Nome = nome;
            EscolherCarregamento(model.Carga, TipoCarregamento.Autocompletar);
            Servico.Filtrar(model);
            return Json(model.Colecao.Select(ent => new { ent.Id, ent.Nome }));
        }

        [Authorize]
        public virtual ActionResult Form(long? id)
        {
            if (id.HasValue)
            {
                TEntidadeFormModel model = Activator.CreateInstance<TEntidadeFormModel>();
                Carga<T> carga = new Carga<T>();
                EscolherCarregamento(carga, TipoCarregamento.Unico);
                Servico.Consultar(model, id.Value, carga);
                return View(model);
            }
            else
            {
                return View();               
            }
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Form(TEntidadeFormModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Servico.Salvar(model);
                    return RedirectToAction("Index");
                }
            }
            catch (StorytellingException ex)
            {
                MensagemExcecao = ex.Message;
            }
                    
            return View(model);
        }

        [Authorize]
        public virtual ActionResult Excluir(long? id)
        {
            try
            {
                if (id.HasValue)
                {
                    Servico.Excluir(id.Value);
                }
            }
            catch (StorytellingException ex)
            {
                MensagemExcecao = ex.Message;
            }

            return RedirectToAction("Index");
        }
    }
}
